﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Text;

namespace Document.Library
{
    /// <summary>
    /// 图片操作帮助类
    /// </summary>
    public class ImageHelper
    {

        /// <summary>
        /// 保存图片并返回路径
        /// </summary>
        /// <param name="base64"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string SaveBase64Image(string base64, string imageType, string webRootPath, string type = ".png")
        {
            //文件名
            DateTime dt = DateTime.Now;

            string filename = string.Format("{0:yyMMdd}", dt).ToString() + Guid.NewGuid().ToString().Replace("-", "").ToUpper() + type;

            //虚拟路径
            string path = $"{webRootPath}/Files/{imageType}/";
            //物理路径
            string basepath = path + filename;
            //不存在文件夹则创建文件夹
            if (!Directory.Exists(path))
            {
                new DirectoryInfo(path).Create();
            }
            MemoryStream outMs = null;
            Bitmap bitmap = Base64ToImage(base64, out outMs);
            bitmap.Save(basepath);
            bitmap.Dispose();
            outMs.Dispose();

            return $"/Files/{imageType}/" + filename;
        }


        /// <summary>
        /// base64转位图（一定要bmp.Dispose()）
        /// </summary>
        /// <param name="base64"></param>
        /// <returns></returns>
        public static Bitmap Base64ToImage(string base64, out MemoryStream outMs)
        {
            base64 = base64.Replace("\\n", "\n").Replace(" ", "+");
            byte[] arr = Convert.FromBase64String(base64.Substring(base64.IndexOf("base64,") + 7));
            outMs = new MemoryStream(arr);
            Bitmap bmp = new Bitmap(outMs);
            //ms.Close();
            return bmp;
        }



        /// <summary>
        /// 删除该名称已有图片，保存最新图片
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="basepath"></param>
        /// <param name="base64"></param>
        /// <returns></returns>
        public static bool RemoveAndSaveImage(string filePath, string basepath, string base64)
        {
            bool result = false;
            try
            {
                //不存在文件夹则创建文件夹
                if (!Directory.Exists(filePath))
                {
                    new DirectoryInfo(filePath).Create();
                }
                //存在该文件，就先删除图片
                if (FileHelper.FileExists(basepath))
                {
                    FileHelper.DeleteFile(basepath);
                }
                Bitmap bitmap = Base64Helper.Base64ToImage(base64);
                bitmap.Save(basepath);
                bitmap.Dispose();
                result = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        /// <summary>
        /// 压缩并保存图片
        /// </summary>
        /// <param name="filePath">文件夹</param>
        /// <param name="basepath">图片保存路劲</param>
        /// <param name="base64">图片base64数据</param>
        /// <param name="ratio">压缩比例 0-1</param>
        /// <returns></returns>
        public static bool CompressAndSaveImage(string filePath, string basepath, string base64, double ratio)
        {
            bool result = false;
            try
            {
                //不存在文件夹则创建文件夹
                if (!Directory.Exists(filePath))
                {
                    new DirectoryInfo(filePath).Create();
                }
                //不存在该文件，就创建保存图片
                if (!FileHelper.FileExists(basepath))
                {
                    Bitmap bitmap = Base64Helper.Base64ToImage(base64);

                    //压缩图片
                    Size compressSize = new Size();
                    compressSize.Width = Convert.ToInt32(bitmap.Width * ratio);
                    compressSize.Height = Convert.ToInt32(bitmap.Height * ratio);
                    bitmap = GetImageThumb(bitmap, compressSize);
                    bitmap.Save(basepath);
                    bitmap.Dispose();
                    result = true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        /// <summary>
        /// 图片压缩
        /// </summary>
        /// <param name="mg"></param>
        /// <param name="newSize"></param>
        /// <returns></returns>
        public static Bitmap GetImageThumb(Bitmap mg, Size newSize)
        {
            Bitmap bp;
            double ratio = 0d;
            double myThumbWidth = 0d;
            double myThumbHeight = 0d;
            int x = 0;
            int y = 0;

            try
            {
                if ((mg.Width / Convert.ToDouble(newSize.Width)) > (mg.Height /
                Convert.ToDouble(newSize.Height)))
                    ratio = Convert.ToDouble(mg.Width) / Convert.ToDouble(newSize.Width);
                else
                    ratio = Convert.ToDouble(mg.Height) / Convert.ToDouble(newSize.Height);
                myThumbHeight = Math.Ceiling(mg.Height / ratio);
                myThumbWidth = Math.Ceiling(mg.Width / ratio);

                Size thumbSize = new Size((int)newSize.Width, (int)newSize.Height);
                bp = new Bitmap(newSize.Width, newSize.Height);
                x = (newSize.Width - thumbSize.Width) / 2;
                y = (newSize.Height - thumbSize.Height);
                Graphics g = Graphics.FromImage(bp);
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                Rectangle rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
                g.DrawImage(mg, rect, 0, 0, mg.Width, mg.Height, GraphicsUnit.Pixel);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return bp;
        }

        /// <summary>
        /// 图片压缩
        /// </summary>
        /// <param name="sFile"></param>
        /// <param name="outPath"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        public static bool GetImageThumb(string sFile, string outPath, int flag)
        {
            using (Image iSource = Image.FromFile(sFile))
            {
                ImageFormat tFormat = iSource.RawFormat;

                //以下代码为保存图片时，设置压缩质量  
                EncoderParameters ep = new EncoderParameters();
                long[] qy = new long[1];
                qy[0] = flag;//设置压缩的比例1-100  
                EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
                ep.Param[0] = eParam;
                try
                {
                    ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                    ImageCodecInfo jpegICIinfo = null;
                    for (int x = 0; x < arrayICI.Length; x++)
                    {
                        if (arrayICI[x].FormatDescription.Equals("JPEG"))
                        {
                            jpegICIinfo = arrayICI[x];
                            break;
                        }
                    }
                    if (jpegICIinfo != null)
                    {
                        iSource.Save(outPath, jpegICIinfo, ep);//dFile是压缩后的新路径  
                    }
                    else
                    {
                        iSource.Save(outPath, tFormat);
                    }
                    return true;
                }
                catch
                {
                    return false;
                }
                finally
                {
                    iSource.Dispose();
                    iSource.Dispose();
                }
            }
        }
    }
}
